﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using Terraria;
using Terraria.Audio;
using Terraria.GameContent;
using Terraria.ID;
using Terraria.ModLoader;

namespace HardcoreGame.Content.Projectiles.Sentries
{
    internal class MegaWrench : ModProjectile
    {
        public override void SetStaticDefaults()
        {
            Main.projFrames[Projectile.type] = 6;
            ProjectileID.Sets.MinionTargettingFeature[Projectile.type] = true;
        }
        public override void SetDefaults()
        {
            Projectile.width = 26;
            Projectile.height = 54;
            Projectile.friendly = true;
            Projectile.sentry = true;
            Projectile.timeLeft = Projectile.SentryLifeTime;
            Projectile.ignoreWater = true;
            Projectile.tileCollide = true;
            Projectile.manualDirectionChange = true;
            Projectile.penetrate = -1;
        }

        public override bool PreDraw(ref Color lightColor)
        {
            Vector2 vector43 = Projectile.position + new Vector2(Projectile.width, Projectile.height) / 2f + Vector2.UnitY * Projectile.gfxOffY - Main.screenPosition;
            Texture2D texture2D33 = TextureAssets.Projectile[Projectile.type].Value;
            Texture2D textureGlow = ModContent.Request<Texture2D>(Texture + "_Glow").Value;
            Texture2D textureRear = ModContent.Request<Texture2D>(Texture + "_Rearfin").Value;
            Rectangle rectangle17 = texture2D33.Frame(1, Main.projFrames[Projectile.type], 0, Projectile.frame);
            Color alpha5 = Projectile.GetAlpha(lightColor);
            Vector2 origin11 = rectangle17.Size() / 2f;
            SpriteEffects spriteEffects = SpriteEffects.None;
            if (Projectile.spriteDirection == -1)
            {
                spriteEffects = SpriteEffects.FlipVertically;
            }
            Main.spriteBatch.Draw(textureRear, vector43, rectangle17, alpha5, Projectile.rotation, origin11, Projectile.scale, spriteEffects, 0f);
            Texture2D texture2D34 = ModContent.Request<Texture2D>(Texture + "_Base").Value;
            Vector2 position16 = Projectile.Bottom + Vector2.UnitY * Projectile.gfxOffY - Main.screenPosition;
            Vector2 origin12 = texture2D34.Size() * new Vector2(0.5f, 1f);
            origin12.Y -= 2f;
            Main.spriteBatch.Draw(texture2D34, position16, null, alpha5, 0f, origin12, 1f, SpriteEffects.None, 0f);
            origin11.X += ((Enum)(object)spriteEffects).HasFlag((Enum)(object)SpriteEffects.FlipHorizontally).ToDirectionInt();
            vector43.Y += 1f;
            vector43.Y += 2f;
            Color color = new(255, 255, 255, Projectile.alpha);
            Main.spriteBatch.Draw(texture2D33, vector43, rectangle17, alpha5, Projectile.rotation, origin11, Projectile.scale, spriteEffects, 0f);
            Main.spriteBatch.Draw(textureGlow, vector43, rectangle17, color, Projectile.rotation, origin11, Projectile.scale, spriteEffects, 0f);
            return false;
        }
        public override bool? CanHitNPC(NPC target)
        {
            return false;
        }
        public override bool CanHitPlayer(Player target)
        {
            return false;
        }
        public override bool CanHitPvp(Player target)
        {
            return false;
        }

        public override bool? CanCutTiles()
        {
            return false;
        }

        public override bool OnTileCollide(Vector2 oldVelocity)
        {
            return false;
        }

        public override bool TileCollideStyle(ref int width, ref int height, ref bool fallThrough, ref Vector2 hitboxCenterFrac)
        {
            fallThrough = false;
            return true;
        }
        private int CustomBallista_FindTarget(float shot_range, float deadBottomAngle, Vector2 shootingSpot)
        {
            int num = -1;
            NPC ownerMinionAttackTargetNPC = Projectile.OwnerMinionAttackTargetNPC;
            if (ownerMinionAttackTargetNPC != null && ownerMinionAttackTargetNPC.CanBeChasedBy(this, false))
            {
                for (int i = 0; i < 1; i++)
                {
                    if (ownerMinionAttackTargetNPC.CanBeChasedBy(this, true))
                    {
                        float num2 = Vector2.Distance(shootingSpot, ownerMinionAttackTargetNPC.Center);
                        if (num2 <= shot_range)
                        {
                            Vector2 vector = (ownerMinionAttackTargetNPC.Center - shootingSpot).SafeNormalize(Vector2.UnitY);
                            if ((Math.Abs(vector.X) >= Math.Abs(vector.Y) * deadBottomAngle || vector.Y <= 0f) && (num == -1 || num2 < Vector2.Distance(shootingSpot, Main.npc[num].Center)) && Collision.CanHitLine(shootingSpot, 0, 0, ownerMinionAttackTargetNPC.Center, 0, 0))
                            {
                                num = ownerMinionAttackTargetNPC.whoAmI;
                            }
                        }
                    }
                }
                if (num != -1)
                {
                    return num;
                }
            }
            for (int j = 0; j < 200; j++)
            {
                NPC nPC = Main.npc[j];
                if (nPC.CanBeChasedBy(this, true))
                {
                    float num3 = Vector2.Distance(shootingSpot, nPC.Center);
                    if (num3 <= shot_range)
                    {
                        Vector2 vector2 = (nPC.Center - shootingSpot).SafeNormalize(Vector2.UnitY);
                        if ((Math.Abs(vector2.X) >= Math.Abs(vector2.Y) * deadBottomAngle || vector2.Y <= 0f) && (num == -1 || num3 < Vector2.Distance(shootingSpot, Main.npc[num].Center)) && Collision.CanHitLine(shootingSpot, 0, 0, nPC.Center, 0, 0))
                        {
                            num = j;
                        }
                    }
                }
            }
            return num;
        }

        public bool shouldApplyESBuffs = true;

        public float shootCool = 0;
        public bool canDoStartup = true;
        public bool canBeep = true;

        public override void AI()
        {
            Projectile.velocity.Y += 0.2f;

            if (Projectile.velocity.Y > 16f)
            {
                Projectile.velocity.Y = 16f;
            }

            float shot_range = 725f;
            float deadBottomAngle = 0.75f;
            float shootCoolMax = 7;
            float frameTimerMax = 3;
            bool hasTarget = false;
            int bulletType = (int)Projectile.ai[0];
            float shootSpeed = Projectile.ai[1];


            if (shootCoolMax < 3)
            {
                shootCoolMax = 3;
            }

            if (frameTimerMax < 1)
            {
                frameTimerMax = 1;
            }

            if (shootCool > 0f)
            {
                shootCool--;
            }
            Vector2 center = Projectile.Center;
            float velocityMult = 10f + shootSpeed;
            if (canDoStartup)
            {
                shootCool = shootCoolMax;

                Projectile.direction = Projectile.spriteDirection = Main.player[Projectile.owner].direction;
                canDoStartup = false;
                Projectile.netUpdate = true;
                if (Projectile.direction == -1)
                {
                    Projectile.rotation = 3.14159274f;
                }
            }
            if (!canDoStartup && !hasTarget)
            {
                int myTarget = CustomBallista_FindTarget(shot_range, deadBottomAngle, center);
                if (myTarget != -1)
                {
                    Vector2 vector = (Main.npc[myTarget].Center - center).SafeNormalize(Vector2.UnitY);
                    Projectile.rotation = Projectile.rotation.AngleLerp(vector.ToRotation(), 0.08f);
                    if (Projectile.rotation > 1.57079637f || Projectile.rotation < -1.57079637f)
                    {
                        Projectile.direction = -1;
                    }
                    else
                    {
                        Projectile.direction = 1;
                    }
                    if (Projectile.owner == Main.myPlayer)
                    {
                        Projectile.direction = Math.Sign(vector.X);
                        hasTarget = true;
                        Projectile.netUpdate = true;
                    }
                }
                else
                {
                    hasTarget = false;
                    float targetAngle = 0f;
                    if (Projectile.direction == -1)
                    {
                        targetAngle = 3.14159274f;
                    }
                    Projectile.rotation = Projectile.rotation.AngleLerp(targetAngle, 0.05f);
                }
            }

            if (hasTarget)
            {
                if (shootCool <= 0)
                {
                    if (!Main.dedServ)
                    {
                        SoundEngine.PlaySound(SoundID.Item11, Projectile.Center);
                    }
                    Vector2 vector2 = new(Projectile.direction, 0f);
                    int myTarget2 = CustomBallista_FindTarget(shot_range, deadBottomAngle, center);
                    if (myTarget2 != -1)
                    {
                        vector2 = (Main.npc[myTarget2].Center - center).SafeNormalize(Vector2.UnitX * Projectile.direction);
                    }

                    Projectile.rotation = vector2.ToRotation();
                    if (Projectile.rotation > 1.57079637f || Projectile.rotation < -1.57079637f)
                    {
                        Projectile.direction = -1;
                    }
                    else
                    {
                        Projectile.direction = 1;
                    }
                    Vector2 velocity = vector2 * velocityMult;
                    if (Projectile.owner == Main.myPlayer)
                    {
                        Vector2 perturbedSpeed = new Vector2(velocity.X, velocity.Y).RotatedByRandom(MathHelper.ToRadians(1.5f));
                        int bullet = Projectile.NewProjectile(Projectile.GetSource_FromAI(), new Vector2(Projectile.Center.X, Projectile.Center.Y + 4), perturbedSpeed, ProjectileID.Bullet, Projectile.damage, Projectile.knockBack, Projectile.owner, 0f, 0f);
                        Main.projectile[bullet].DamageType = DamageClass.Summon;
                        Main.projectile[bullet].minion = true;
                    }
                    shootCool = shootCoolMax;
                }
            }
            Projectile.spriteDirection = Projectile.direction;

            if (hasTarget)
            {
                if (canBeep)
                {
                    canBeep = false;
                }

                Projectile.frameCounter++;
                if (Projectile.frameCounter > frameTimerMax)
                {
                    Projectile.frameCounter = 0;
                    Projectile.frame++;
                }

                if (Projectile.frame >= 6)
                {
                    Projectile.frame = 0;
                }
            }
            else
            {
                if (!canBeep)
                {
                    canBeep = true;
                }
                Projectile.frame = 0;
                Projectile.frameCounter = 0;
            }
        }


        public override void OnKill(int timeLeft)
        {
            SoundEngine.PlaySound(SoundID.Item14, Projectile.position);
            int num536;
            for (int num567 = 0; num567 < 7; num567 = num536 + 1)
            {
                Dust.NewDust(new Vector2(Projectile.position.X, Projectile.position.Y), Projectile.width, Projectile.height, 31, 0f, 0f, 100, default(Color), 1.5f);
                num536 = num567;
            }
            for (int num568 = 0; num568 < 3; num568 = num536 + 1)
            {
                int num569 = Dust.NewDust(new Vector2(Projectile.position.X, Projectile.position.Y), Projectile.width, Projectile.height, 6, 0f, 0f, 100, default(Color), 2.5f);
                Main.dust[num569].noGravity = true;
                Dust dust = Main.dust[num569];
                dust.velocity *= 3f;
                num569 = Dust.NewDust(new Vector2(Projectile.position.X, Projectile.position.Y), Projectile.width, Projectile.height, 6, 0f, 0f, 100, default(Color), 1.5f);
                dust = Main.dust[num569];
                dust.velocity *= 2f;
                num536 = num568;
            }
            Vector2 position36 = new(Projectile.position.X - 10f, Projectile.position.Y - 10f);
            int num570 = Gore.NewGore(Projectile.GetSource_Death(), position36, default, Main.rand.Next(61, 64), 1f);
            Gore gore = Main.gore[num570];
            gore.velocity *= 0.3f;
            Gore gore87 = Main.gore[num570];
            gore87.velocity.X = gore87.velocity.X + Main.rand.Next(-10, 11) * 0.05f;
            Gore gore88 = Main.gore[num570];
            gore88.velocity.Y = gore88.velocity.Y + Main.rand.Next(-10, 11) * 0.05f;
        }
    }
}